package jst.btremote.bluetooth;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import jst.btremote.bluetooth.BluetoothConnector.BluetoothSocketWrapper;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class BluetoothCommunication extends Thread {

	private BluetoothDevice device;
	private Handler handler;
	private boolean endFlag = false;

	private BlockingQueue<String> dataQueue = new LinkedBlockingQueue<String>();

	public BluetoothCommunication(BluetoothDevice device, Handler handler) {
		super();
		this.device = device;
		this.handler = handler;
		this.endFlag = false;
	}

	@Override
	public void run() {

		Log.d("JST-Thread", "Thread started");

		BluetoothConnector btConnector = new BluetoothConnector(this.device,
				BluetoothAdapter.getDefaultAdapter());
		String buffer = null;

		while (!endFlag) {
			// read data from internal buffer
			try {
				buffer = this.dataQueue.take();

				if (buffer != null) {
					// create connection if not exists
					if (!btConnector.getConnectionStatus()) {
						try {
							btConnector.connect();
						} catch (IOException e) {
							e.printStackTrace();
							Message message = handler.obtainMessage();
							Bundle bundle = new Bundle();
							bundle.putString("message",
									"Failed to connect to device");
							message.setData(bundle);
							handler.sendMessage(message);
						}
					}
					if (btConnector.getConnectionStatus()) {
						try {
							BluetoothSocketWrapper bluetoothSocket = btConnector
									.getBluetoothSocket();
							if (bluetoothSocket == null) {
								// return log
								Log.e("JST", "bluetoothSocket NULL");
								Message message = handler.obtainMessage();
								Bundle bundle = new Bundle();
								bundle.putString("message",
										"bluetoothSocket NULL");
								message.setData(bundle);
								handler.sendMessage(message);
							} else {
								OutputStream outStream = bluetoothSocket
										.getOutputStream();
								if (outStream == null) {
									// return log
									Log.e("JST", "Outstream NULL");
									Message message = handler.obtainMessage();
									Bundle bundle = new Bundle();
									bundle.putString("message",
											"Outstream NULL");
									message.setData(bundle);
									handler.sendMessage(message);
								} else {
									// send message
									StringBuilder strBuilder = new StringBuilder();
									// send STX for end
									//strBuilder.append(new byte[] { 0x02 });
									strBuilder.append(buffer);
									// send ETX for end
									//strBuilder.append(new byte[] { 0x03 });
									
									String strBuffer = strBuilder.toString();
									outStream.write(new byte[] { 0x02 });
									
									outStream.write(strBuffer.getBytes(Charset
											.forName("US-ASCII")));
									outStream.write(new byte[] { 0x03 });
									// return log
									Log.d("JST", "Send: " + strBuffer);
									Message message = handler.obtainMessage();
									Bundle bundle = new Bundle();
									bundle.putString("message", "Message send");
									message.setData(bundle);
									handler.sendMessage(message);
								}
							}
						} catch (IOException e) {
							// return log
							e.printStackTrace();
							Log.e("JST", "Error while sending");
							Message message = handler.obtainMessage();
							Bundle bundle = new Bundle();
							bundle.putString("message", "Error while sending!");
							message.setData(bundle);
							handler.sendMessage(message);
						}
					}
				}

			} catch (InterruptedException e1) {
			}
		}

		// close connection if end of thread
		if (btConnector.getConnectionStatus()) {
			try {
				BluetoothSocketWrapper bluetoothSocket = btConnector
						.getBluetoothSocket();
				if (bluetoothSocket != null) {
					bluetoothSocket.close();
				}
			} catch (IOException e) {
			}
		}

		Log.d("JST-Thread", "Thread ended");
	}

	public void endCommunication() {
		this.endFlag = true;
		this.interrupt();
	}

	public void sendMessage(String message) {
		if (!this.isAlive()) {
			this.start();
		}
		this.dataQueue.add(message);
		Log.d("JST", "Message: " + message);
	}

}
